package com.chuanke.ckfamily.service.user.impl;

import com.chuanke.ckfamily.dao.user.UserRelationDao;
import com.chuanke.ckfamily.dao.user.model.Friend;
import com.chuanke.ckfamily.dao.user.model.User;
import com.chuanke.ckfamily.dao.user.model.UserRelation;
import com.chuanke.ckfamily.service.base.FailCode;
import com.chuanke.ckfamily.service.common.CacheService;
import com.chuanke.ckfamily.service.common.WyService;
import com.chuanke.ckfamily.service.common.impl.RedisLockUtil;
import com.chuanke.ckfamily.service.constant.SpecialRelationConstant;
import com.chuanke.ckfamily.service.constant.UserRelationType;
import com.chuanke.ckfamily.service.exception.CFException;
import com.chuanke.ckfamily.service.social.SpecialRelationService;
import com.chuanke.ckfamily.service.user.ChanagedFriends;
import com.chuanke.ckfamily.service.user.FriendApplyService;
import com.chuanke.ckfamily.service.user.UserRelationService;
import com.chuanke.ckfamily.service.user.UserService;
import com.weijie.core.BaseBiz;
import com.weijie.core.util.DateUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserRelationServiceImpl extends BaseBiz<UserRelation, UserRelationDao> implements UserRelationService {

	private static final Logger log = LoggerFactory.getLogger(UserRelationServiceImpl.class);

	@Autowired
	private UserService userService;

	@Autowired
	private FriendApplyService friendApplyService;

	@Autowired
	private WyService wyService;

	@Autowired
	private CacheService cacheService;
	
	@Autowired
	private SpecialRelationService specialRelationService;

	@Override
	public UserRelation getUserRelation(Long master, Long slave) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("master", master);
		param.put("slave", slave);
		return baseDao.getRelationship(param);
	}

	@Override
	public boolean isFriend(Long master, Long slave) {
		UserRelation userRelation = getUserRelation(master, slave);
		if (userRelation != null && userRelation.getType() == UserRelationType.FRIEND.getType()) {
			return true;
		}
		return false;
	}

	@Override
	public ChanagedFriends getFriends(Long uid, String date) throws CFException {
		if (null == userService.findById(uid)) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("uid", uid);
		ChanagedFriends chanagedFriends = new ChanagedFriends();

		if (date == null || date == "" || "0" == date) {
			List<Friend> friends = baseDao.getNewFriends(param);
			chanagedFriends.setNewFreinds(friends);
			chanagedFriends.setDate(DateUtils.dateToTimeStamp(new Date()));
			return chanagedFriends;
		}

		Timestamp time;
		try {
			long temp = new Long(date);
			time = new Timestamp(temp);
			param.put("date", time);
		} catch (Exception e) {
			throw new CFException(FailCode.APP, "时间格式不正确");
		}
		chanagedFriends.setNewFreinds(baseDao.getNewFriends(param));
		chanagedFriends.setUpdateFriends(baseDao.getUpdateFriends(param));
		chanagedFriends.setRemovedFriends(baseDao.getRemovedFriends(param));
		chanagedFriends.setDate(DateUtils.dateToTimeStamp(new Date()));
		return chanagedFriends;
	}

	@Override
	public void updateFriendRemark(Long master, Long slave, String remark) throws CFException {
		User muser = userService.findById(master);
		User suser = userService.findById(slave);
		if (null == muser || null == suser) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}

		UserRelation userRelation = getUserRelation(master, slave);
		if (userRelation != null && userRelation.getType() == UserRelationType.FRIEND.getType()) {
			updateUserRelation(userRelation, userRelation.getType(), remark);
			if (suser.hasWyId()) {
				wyService.updateFriend(muser.getUser_no(), suser.getUser_no(), remark, null);
			}

		} else {
			throw new CFException(FailCode.FRIEND_RELATION_NOT_EXIST);

		}
	}

	@Override
	public void deleteFriend(Long master, Long slave) throws CFException {
		log.info("delete friend =======> mast={}, slave={}", master, slave);
		User muser = userService.findById(master);
		User suser = userService.findById(slave);
		if (null == muser || null == suser) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}

		UserRelation userRelation1 = getUserRelation(master, slave);
		if (userRelation1 != null && userRelation1.getType() == UserRelationType.FRIEND.getType()) {
			log.info("delete friend 1=======> mast={}, slave={}", master, slave);
			updateFriendRelation(master, slave, UserRelationType.DELETE.getType());
			friendApplyService.deleteApply(master, slave);
			this.deleteBlackWy(master, slave);
			wyService.deleteFriend(muser.getUser_no(), suser.getUser_no());
			this.createBlackWy(master, slave);
			log.info("delete friend 2=======> mast={}, slave={}", master, slave);
		}
	}
	@Override
	public void createBlackWy(Long uid, Long tuserId)throws CFException {
		boolean isBlack = specialRelationService.isBlack(uid, tuserId);
		if (isBlack) {
			specialRelationService.black(uid, tuserId, SpecialRelationConstant.relation_value_blackMute);
		}

		boolean tisBlack = specialRelationService.isBlack(tuserId, uid);
		if (tisBlack) {
			specialRelationService.black(tuserId, uid, SpecialRelationConstant.relation_value_blackMute);
		}

		if (!isBlack && !tisBlack) {
			specialRelationService.black(tuserId, uid, SpecialRelationConstant.relation_value_unBlackMute);
			specialRelationService.black(uid, tuserId, SpecialRelationConstant.relation_value_unBlackMute);
		}
	}

	@Override
	public void deleteBlackWy(Long uid, Long tuserId) throws CFException {
		User user = userService.findById(uid);
		User tuser = userService.findById(tuserId);
		
		wyService.setSpecialRelation(user.getUser_no(), tuser.getUser_no(), SpecialRelationConstant.relation_type_black, SpecialRelationConstant.relation_value_unBlackMute);
		wyService.setSpecialRelation(tuser.getUser_no(), user.getUser_no(), SpecialRelationConstant.relation_type_black, SpecialRelationConstant.relation_value_unBlackMute);
		
	}

	@Override
	public void addUserRelation(Long requester, Long responser, String remark) throws CFException {
		User muser = userService.findById(requester);
		User suser = userService.findById(responser);

		UserRelation userRelation = getUserRelation(requester, responser);
		if (userRelation == null) {
			userRelation = new UserRelation();
			userRelation.setMaster(requester);
			userRelation.setSlave(responser);
			userRelation.setType(UserRelationType.FRIEND.getType());
			userRelation.setFriend_remark(remark);
			userRelation.setUpdate_time(new Timestamp(System.currentTimeMillis()));
			userRelation.setCreate_time(new Timestamp(System.currentTimeMillis()));
			baseDao.add(userRelation);

		} else {
			updateUserRelation(userRelation, UserRelationType.FRIEND.getType(), remark);

		}
		wyService.addFriend(muser.getUser_no(), suser.getUser_no());
	}

	private void updateUserRelation(UserRelation userRelation, Integer type, String remark) {
		UserRelation temp = new UserRelation();
		temp.setId(userRelation.getId());
		temp.setType(type);
		temp.setFriend_remark(remark);
		if (type != null && type == UserRelationType.FRIEND.getType()) {
			temp.setCreate_time(new Timestamp(System.currentTimeMillis()));
		}
		temp.setUpdate_time(new Timestamp(System.currentTimeMillis()));
		baseDao.update(temp);
	}

	private void updateFriendRelation(Long master, Long slave, Integer type){
		Map<String, Object> param = new HashMap<>();
		param.put("type", type);
		param.put("master", master);
		param.put("slave", slave);
		baseDao.updateFriendRelation(param);
		
	}
}